﻿using System;
using System.Collections.Generic;
using System.Text;
using FT.TouchScreen.Terminal.Model;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

namespace FT.TouchScreen.Terminal.Util.Impl
{
    public class DefaultPersonNavigator:IPersonNavigator
    {

        private PictureBox personPic=null;
        private int stepDistance = 5;
        private int sleepSeconds = 1;
        private Control panel = null;
        private Thread drawThread = null;
        private bool hasDrawPath = false;
        private string[] paths = null;
        private Color roadColor = Color.Red;
        private int roadWidth = 5;
        private DotNode dotStart = null;

        private Pen roadPen = null;

        public bool HasDrawPath
        {
            get { return hasDrawPath; }
            set { hasDrawPath = value; }
        }

        public DefaultPersonNavigator(Control panel, PictureBox person, Color roadColor, int roadWidth, int distance, int seconds)
        {
            this.personPic = person;
            this.stepDistance = distance;
            this.sleepSeconds = seconds;
            this.roadColor = roadColor;
            this.roadWidth = roadWidth;
            this.roadPen=new Pen(this.roadColor, this.roadWidth);
            this.panel = panel;
           // this.personPic.Visible = false;
        }
        public void LocationPerson(int X, int Y)
        {
            Console.WriteLine("当前要定位的图片位置将位于X：" + X + "  Y:" + Y);
            // graphic.DrawLine(this.roadPen, this.pointStartBefore, this.pointEndBefore);
            this.personPic.Location = new Point(X + this.roadWidth, Y - this.personPic.Height - this.roadWidth);
        }

        private void LocationThePerson(Graphics graphic, int X, int Y)
        {
            Console.WriteLine("当前要定位的图片位置将位于X："+X+"  Y:"+Y);
           // graphic.DrawLine(this.roadPen, this.pointStartBefore, this.pointEndBefore);
            this.personPic.Location = new Point(X+this.roadWidth,Y-this.personPic.Height-this.roadWidth);
        }
        private Point pointStartBefore = new Point(0,0);
        private Point pointEndBefore = new Point(0,0);

        private void DrawPath(Graphics graphic ,int startX, int startY, int endX, int endY)
        {
            Console.WriteLine("当前要绘画的路径将于起点坐标X：" + startX + "  Y:" + startY+" 终点坐标为X："+endX+" Y:"+endY);
            /*
            if (startX+this.roadWidth >=endX)
            {
                this.personPic.Location = new Point(X + this.roadWidth, Y + this.roadWidth);
            }
            else if (startY == endY)
            {
                startY += this.personPic.Height;
            }
            */
            this.pointStartBefore=new Point(startX , startY);
            this.pointEndBefore=new Point(endX, endY);
            graphic.DrawLine(this.roadPen,this.pointStartBefore ,this.pointEndBefore );
        }

        private void DrawNavigatePathBetweenTwoNode(Graphics graphic, DotNode begin, DotNode end)
        {
            Console.WriteLine("当前要导航的节点之间将于起点"+begin.Name+"坐标X：" + begin.X + "  Y:" + begin.Y + " 终点"+end.Name+"坐标为X：" + end.X + " Y:" + end.Y);
            /*
            int xDistance = end.X - begin.X;
            int yDistance = end.Y - begin.Y;
            int step = Math.Abs(xDistance) / stepDistance;
            int stepY=0;
            if (step == 0)
            {
               
                if (Math.Abs(yDistance) % stepDistance != 0)
                {
                    step += 1;
                }
                stepY = Math.Abs(yDistance) / stepDistance;
            }
            else
            {
               
                if (Math.Abs(xDistance) % stepDistance != 0)
                {
                    step += 1;
                }
                stepY = Math.Abs(yDistance) / step;
            }
           
            
            int tmpx = begin.X;
            int tmpy = begin.Y;
            int tmpXPre = tmpx;
            int tmpYPre = tmpy;
            for (int i = 0; i < step; i++)
            {
                if (i == step - 1)
                {
                    tmpx = end.X;
                    tmpy = end.Y;
                }
                else
                {
                    if (xDistance > stepDistance)
                    {
                        tmpx = begin.X + i*stepDistance;
                    }
                    else if (0 < xDistance&&xDistance < stepDistance)
                    {
                        tmpx = end.X - stepDistance * i;
                    }
                    else
                    {
                        
                    }
                    if (yDistance < 0)
                    {
                        tmpy = begin.Y + i * stepY;
                    }
                    else
                    {
                        tmpy = end.Y - i * stepY;
                    }
                }
            
               
                this.LocationThePerson(graphic,tmpx,tmpy);
                this.DrawPath(graphic, tmpXPre, tmpYPre, tmpx, tmpy);
                tmpXPre = tmpx;
                tmpYPre = tmpy;
                System.Threading.Thread.Sleep(this.sleepSeconds);
            }
             * */

            int tmpx = begin.X;
            int tmpy = begin.Y;
            this.LocationThePerson(graphic, end.X, end.Y);
            this.DrawPath(graphic, begin.X, begin.Y, end.X,end.Y);

            System.Threading.Thread.Sleep(this.sleepSeconds);
        }

        private void DrawNavigatePath()
        {
            try
            {
                if (this.paths != null && this.paths.Length > 0)
                {

                    Pen pen = new Pen(Color.Red, 4);
                    Graphics graphic = this.panel.CreateGraphics();
                    graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    // graphic.Clear(Color.);
                    DotNode dotPre = this.dotStart;
                    DotNode dotNext = null;
                    for (int i = 0; i < paths.Length; i++)
                    {
                        if (paths[i].Trim().Length > 0)
                        {
                            dotNext = MinShortPathHelper.ht[paths[i].Trim()] as DotNode;
                            this.DrawNavigatePathBetweenTwoNode(graphic, dotPre, dotNext);
                            // graphic.DrawLine(pen, new Point(dotPre.X, dotPre.Y), new Point(dotNext.X, dotNext.Y));
                            dotPre = dotNext;
                            //break;

                        }
                    }
                    graphic.Dispose();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }


        #region IPersonNavigator 成员

        public void SetRoadPen(Pen pen)
        {
            this.roadPen = pen;
        }

        public int Navigate(string start, string end)
        {
            if (this.drawThread != null)
            {
                this.drawThread.Interrupt();
            }
            if (start == "") return 0;
            if (end == "") return 0;

            DotNode gnStart = MinShortPathHelper.ht[start] as DotNode;
            DotNode gnEnd = MinShortPathHelper.ht[end] as DotNode;
            if (gnStart == null || gnEnd == null)
            {
                MessageBox.Show("The path begin or end node is null!");
                return 0;
            }
            gnStart.SetRank(null);
            gnStart.BFind = true;
            List<DotNode> arrGN = new List<DotNode>();
            arrGN.Add(gnStart);
            MinShortPathHelper.InitRank(arrGN);
            MinShortPathHelper.FindMin(arrGN, gnEnd);
#if DEBUG
            Console.WriteLine("导航结果为：" + gnEnd.MinDist.ToString() + "\r\n" + gnEnd.Path);//在界面显示结果
#endif
            
           // DotNode dotNext = null;
            this.dotStart = gnStart;
            string[] pathsTmp = gnEnd.Path.Split(',');
            this.paths = pathsTmp;
            this.drawThread = new Thread(new ThreadStart(DrawNavigatePath));
            this.drawThread.Start();
            return gnEnd.MinDist;
            
        }

        #endregion
    }
}
